perm filename MIXIO[MIX,SYS] blob
sn#020792 filedate 1972-03-08 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00002 00002 Various I/O button routines
00008 00003 "Input-output" operations.
00013 00004 The IN instruction
00017 00005 The OUT instruction
00023 00006 These are the device specific sections.
00032 00007 these are the other i/o related operations
00037 ENDMK
⊗;
COMMENT ⊗ Various I/O button routines ⊗
QREAD: SKIPE CRDBLK ; 0 → NOT INITED
JRST QRD1
INIT 10, 10 ; INIT IN IMAGE MORE
SIXBIT /DSK/
CRDBLK+1
JRST ZDISK ; ERROR RETURN
PUSHJ P,RESCN ;*RES* LOOK FOR NAME ON PREV LINE
PUSHJ P,FINFI2 ;*RES* LOOK IT UP
JRST .+3 ;*RES* RESCN SKIPS 2 IF NO ARG
OUTSTR [ASCIZ ⊗FILE FOR CARD READER INPUT: ⊗]
FINFO ; GET FILE DATA
MOVE 10, [XWD BLK, CRDBLK+4] ; PUT DATA IN CRDBLK
BLT 10, CRDBLK+7
LOOKUP 10, CRDBLK+4 ; LOOKUP FILE
JRST .-5 ; ERROR → TRY AGAIN
AOS CRDBLK ; I/0 STATUS WORD ← +1
JRST BUTTON
QRD1: OUTSTR [ASCIZ ⊗READ FILE ALREADY OPEN⊗] ;*RES*
JRST QBUTN ;*RES*
QREADX: RELEAS 10, 0 ; CLOSE AND RELEAS CHANNEL
SETZM CRDBLK ; RESET I/O STATUS WORD
JRST BUTTON
QPUNCH: SKIPE CPNBLK ; 0 → NOT INITED
JRST QPN1
INIT 11, 10 ; INIT IN IMAGE MORE
SIXBIT /DSK/
XWD CPNBLK+1, 0
JRST ZDISK ; ERROR RETURN
PUSHJ P,RESCN ;*RES* LOOK FOR NAME ON PREV LINE
PUSHJ P,FINFI2 ;*RES* LOOK IT UP
JRST .+3 ;*RES* RESCN SKIPS 2 IF NO ARG
OUTSTR [ASCIZ ⊗FILE FOR CARD PUNCH OUTPUT: ⊗]
FINFO ; GET FILE DATA
MOVE 10, [XWD BLK, CPNBLK+4] ; PUT DATA IN CPNBLK
BLT 10, CPNBLK+7
ENTER 11, CPNBLK+4 ; ENTER FILE
JRST .-5 ; ERROR → TRY AGAIN
AOS CPNBLK ; I/0 STATUS WORD ← +1
JRST BUTTON
QPN1: OUTSTR [ASCIZ ⊗PUNCH FILE ALREADY OPEN⊗] ;*RES*
JRST QBUTN ;*RES*
QPNCHX: RELEAS 11, 0 ; CLOSE AND RELEAS CHANNEL
SETZM CPNBLK ; RESET I/O STATUS WORD
JRST BUTTON
QPRINT: SKIPE PRNBLK ; 0 → NOT INITED
JRST QPR1
INIT 12, 10 ; INIT IN IMAGE MORE
SIXBIT /DSK/
XWD PRNBLK+1, 0
JRST ZDISK ; ERROR RETURN
PUSHJ P,RESCN ;*RES* LOOK FOR NAME ON PREV LINE
PUSHJ P,FINFI2 ;*RES* LOOK IT UP
JRST .+3 ;*RES* RESCN SKIPS 2 IF NO ARG
OUTSTR [ASCIZ ⊗FILE FOR PRINTER OUTPUT: ⊗]
FINFO ; GET FILE DATA
MOVE 10, [XWD BLK, PRNBLK+4] ; PUT DATA IN PRNBLK
BLT 10, PRNBLK+7
ENTER 12, PRNBLK+4 ; ENTER FILE
JRST .-5 ; ERROR → TRY AGAIN
AOS PRNBLK ; I/0 STATUS WORD ← +1
JRST BUTTON
QPR1: OUTSTR [ASCIZ ⊗PRINT FILE ALREADY OPEN⊗] ;*RES*
JRST QBUTN ;*RES*
QPRNTX: RELEAS 12, 0 ; CLOSE AND RELEAS CHANNEL
SETZM PRNBLK ; RESET I/O STATUS WORD
JRST BUTTON
QBUTN: INCHWL 10 ;*RES* READ REST OF LINE
CAIE 10,12 ;*RES* UP TO THE LF
JRST .-2
JRST BUTTON ;*RES* THEN GO TO BUTTON
COMMENT ⊗ "Input-output" operations.
At present (6-25-70), the only devices planned for this MIX
machine are the following:
card reader `CRD' F=16 chan=10
card punch `CPN' F=17 chan=11
printer `PRN' F=18 chan=12
typewriter(in) `TIN' F=19 chan=13
typewriter(out) `TOT' F=19 chan=14
The simulation of i/o for CRD, CPN, PRN will be done through the
use of disk files.
Each device will have a device block of 8 words, containing
the following information:
word 1 an i/o status word
words 2-4 i/o buffer for the system
words 5-8 file info for LOOKUP or ENTER
TIN and TOT will be done directly to and from the teletype.
In addition, a copy of everything printed on the teletype
during each use of MIXSIM will be saved on a file called
MIXTTY. This will enable the user to obtain hard copies of
everything.
⊗
COMMENT ⊗ This subroutine takes the MIX character in register 10
and puts it into the appropriate place in MIXBUF (using
a byte pointer in 11). If this fills MIXBUF, the routine
moves MIXBUF to the address in MIXAD, increments MIXAD,
resets the byte pointer in 11, and zeros out MIXBUF.
Called by "CTOMIX"
⊗
OPDEF CTOMIX [PUSHJ P, .]
IDPB 10, 11 ; PUT BYTE INTO MIXBUF
TLNE 11, 770000 ; LAST BYTE IN MIXBUF?
POPJ P, ; NO → RETURN
MOVE 10, MIXBUF ; YES → PUT INTO MIX CORE
MOVEM 10, @MIXAD
AOS MIXAD ; INCREMENT MIXAD
MOVE 11, [POINT 6, MIXBUF, 5] ; RESET BYTE POINTER
SETZM MIXBUF ; ZERO OUT MIXBUF
POPJ P, ; RETURN
COMMENT ⊗ This subroutine takes the MIX word in register 10
and moves it to the address in MIXAD.
Called by "WTOMIX"
⊗
OPDEF WTOMIX [PUSHJ P, .]
MOVEM 10, @MIXAD ; PUT INTO MIX CORE
AOS MIXAD ; INCREMENT MIXAD
POPJ P, ; RETURN
COMMENT ⊗ This subroutine is similar to CTOMIX, but instead of
putting the characters into MIXBUF, it takes them out
(resetting MIXBUF and MIXAD when necessary).
Called by "CFRMIX"
⊗
OPDEF CFRMIX [PUSHJ P, .]
TLNE 11, 770000 ; LAST BYTE IN MIXBUF?
JRST .+5 ; NO
MOVE 10, @MIXAD ; YES → GET NEXT ONE
MOVEM 10, MIXBUF
AOS MIXAD ; INCREMENT MIXAD
MOVE 11, [POINT 6, MIXBUF, 5] ; RESET POINTER
ILDB 10, 11 ; GET NEXT CHARACTER
POPJ P, ; RETURN
COMMENT ⊗ This is similarly analagous to WTOMIX.
Called by "WFRMIX"
⊗
OPDEF WFRMIX [PUSHJ P, .]
MOVE 10, @MIXAD ; GET NEXT WORD
AOS MIXAD ; INCREMENT MIXAD
POPJ P, ; RETURN
COMMENT ⊗ The IN instruction ⊗
IN: MOVE 12,MSPEC ; GET MEMORY SPECIFICATIONS
ADDI 12, MC0000 ; RELOCATE SO ADDRESSES MIX-CORE
MOVEM 12, MIXAD ; INITIALIZE MIXAD
LDB 11, [POINT 6, INSTR, 29] ; GET FIELD-BYTE
CAILE 11, =19 ; UNIT NUMBER MUST BE ≤19
JRST ZUNIT ; ERROR
SKIPG 13, UNIN(11) ; 13 ← CHANNEL NUMBER AND
JRST ZUNIT ; ERROR IF ZERO
HLRZ 10, LOCK1(11) ; first we wait for this device to finish anything
JUMPE 10, .+4 ; no input on this device
MOVE 10, (10) ; get time for finishing input
CAMLE 10, EXTIME ; has it happened?
MOVEM 10, EXTIME ; no → make it happen
HRRZ 10, LOCK1(11)
JUMPE 10, .+4 ; no output on this device
MOVE 10, (10) ; get time for finishing output
CAMLE 10, EXTIME ; has it happened?
MOVEM 10, EXTIME ; now it has
HRLZ 10, 12 ; now see if any interlocks on the range to work with
HRR 10, LOCK0(11)
ADD 10, 12
SUB 10, [XWD MC0000, MC0000]
MOVEM 10, MLOCK ; now MLOCK has range descriptor
WWLOCK ; test whether it's OK to use this range
JRST ZWLOCK ; no it isn't
LDB 11, [POINT 6, INSTR, 29]
HLRZ 10, LOCK1(11) ; add device to RLOCKT for read-interlock
JUMPE 10, IN1 ; zero → this device doesn't get entered (should never take this jump)
MOVEM 10, LOCK2 ; save base address of entry in table
HLRZ 10, LOCK0(11) ; this gives total interlock time
ADD 10, EXTIME ; so this is time when device is finally ready
MOVEM 10, @LOCK2 ; a fact we should remember
AOS LOCK2 ; for next part of table entry
MOVE 10, MIXAD ; this is base address of locked-out range
SUBI 10, MC0000 ; make it relative to MC0000
MOVEM 10, @LOCK2 ; and remember it
AOS LOCK2 ; get ready for next part of entry
ADD 10, LOCK0(11) ; this gives final address of range
HRRZS 10 ; get rid of garbage in left half
MOVEM 10, @LOCK2 ; and remember this too
IN1: MOVE 11, [POINT 6, MIXBUF, 5] ; INITIALIZE BYTE POINTER TO MIXBUF
SETZM MIXBUF ; ZERO OUT MIXBUF
JRST @INAD(13) ; GO TO APPROPRIATE ADDRESS
INAD: 0
0
0
0
0
0
0
0
INCRD
0
0
INTIN
0
0
0
0
COMMENT ⊗ The OUT instruction ⊗
OUT: MOVE 12,MSPEC ; GET MEMORY SPECIFICATIONS
ADDI 12, MC0000 ; RELOCATE SO ADDRESSES MIX-CORE
MOVEM 12, MIXAD ; INITIALIZE MIXAD
LDB 11, [POINT 6, INSTR, 29] ; GET FIELD-BYTE
CAILE 11, =19 ; UNIT NUMBER MUST BE ≤19
JRST ZUNIT ; ERROR
SKIPG 13, UNOUT(11) ; 13 ← CHANNEL NUMBER AND
JRST ZUNIT ; ERROR IF ZERO
HLRZ 10, LOCK1(11) ; first we wait for this device to finish anything
JUMPE 10, .+4 ; no input on this device
MOVE 10, (10) ; get time for finishing input
CAMLE 10, EXTIME ; has it happened?
MOVEM 10, EXTIME ; no → make it happen
HRRZ 10, LOCK1(11)
JUMPE 10, .+4 ; no output on this device
MOVE 10, (10) ; get time for finishing output
CAMLE 10, EXTIME ; has it happened?
MOVEM 10, EXTIME ; now it has
HRLZ 10, 12 ; now see if any interlocks on the range to work with
HRR 10, LOCK0(11)
ADD 10, 12
SUB 10, [XWD MC0000, MC0000]
MOVEM 10, MLOCK ; now MLOCK has range descriptor
RRLOCK ; test whether it's OK to use this range
JRST ZRLOCK ; no it isn't
LDB 11, [POINT 6, INSTR, 29]
HRRZ 10, LOCK1(11) ; add device to RLOCKT for read-interlock
JUMPE 10, OUT1 ; zero → this device doesn't get entered (should never take this jump)
MOVEM 10, LOCK2 ; save base address of entry in table
HLRZ 10, LOCK0(11) ; this gives total interlock time
ADD 10, EXTIME ; so this is time when device is finally ready
MOVEM 10, @LOCK2 ; a fact we should remember
AOS LOCK2 ; for next part of table entry
MOVE 10, MIXAD ; this is base address of locked-out range
SUBI 10, MC0000 ; make it relative to MC0000
MOVEM 10, @LOCK2 ; and remember it
AOS LOCK2 ; get ready for next part of entry
ADD 10, LOCK0(11) ; this gives final address of range
HRRZS 10 ; get rid of garbage in left half
MOVEM 10, @LOCK2 ; and remember this too
OUT1: MOVE 11, [POINT 6, MIXBUF, 5] ; INITIALIZE BYTE POINTER TO MIXBUF
SETZM MIXBUF ; ZERO OUT MIXBUF
JRST @OUTAD(13) ; GO TO APPROPRIATE ADDRESS
OUTAD: 0
0
0
0
0
0
0
0
0
OUTCPN
OUTPRN
0
OUTTOT
0
0
0
COMMENT ⊗ These tables are used to convert the F unit number
to i/o channels. A `0' indicates that that form of
i/o cannot be done with that unit.
⊗
UNIN: 0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
10 ; CARD READER
0 ; CARD PUNCH CANNOT DO INPUT
0 ; PRINTER CANNTO DO INPUT
13 ; TYPEWRITER
UNOUT: 0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0 ; CARD READER CANNOT DO OUTPUT
11 ; CARD PUNCH
12 ; PRINTER
14 ; TYPEWRITER
MIXAD: 0 ; CONTAINS ADDRESS OF NEXT MIX WORD TO WORRY ABOUT
MIXBUF: 0 ; BUFFER FOR MIX WORDS
IOBUF: 0 ; BUFFER FOR I/O DEVICES
COUNT: 0
LOCK0: repeat =16 {0} ; this table has interlock times and record lengths
XWD =1000, =15 ; CRD: 1000u and 16 words
XWD =1000, =15 ; CPN: 1000u and 16 words
XWD =750, =23 ; PRN: 750u and 24 words
XWD =2000, =13 ; TIN,TOT: 2000u and 14 words
LOCK1: repeat =16 {0} ; this table has address for interlock tables
XWD CRDLOK, 0 ; CRD: read-interlock
XWD 0, CPNLOK ; CPN: write-interlock
XWD 0, PRNLOK ; PRN: write-interlock
XWD TINLOK, TOTLOK ; Typ: both read and write
LOCK2: 0 ; this is just used for temporary stoarage
COMMENT ⊗ These are the device specific sections.
⊗
; ****** CARD READER
CRDBLK: BLOCK 10
INCRD: SKIPN CRDBLK ; I/O STATUS WORD = 0
JRST ZIOBEG ; → NOT INITED YET
PUSHJ P, GETWRD ; GET INPUT WORD
TRNN 10, 1 ; IS IT AN SOS LINE-NUMBER?
JRST .+3 ; NO
PUSHJ P, GETWRD ; YES → GET NEXT WORD
IBP 12 ; AND SKIP <TAB>
MOVEI 10, =80 ; SET UP COUNTER FOR CHARACTERS
MOVEM 10, COUNT
TLNN 12, 760000 ; LAST BYTE IN 13?
PUSHJ P, GETWRD ; YES → GET NEXT WRD
ILDB 10, 12 ; GET NEXT ASCII CHARACTER
CAIN 10, 15 ; CARRIAGE-RETURN →
JRST .+6 ; FINISH LINE WITH BLANKS
MOVE 10, ASCMIX(10) ; CONVERT TO MIX CODE
CTOMIX
SOSE COUNT ; BACK FOR MORE
JRST .-10
JRST .+5 ; NOW GO TO END OF LINE
SETZ 10, ; MIX CODE FOR <BLANK> IS 00
CTOMIX
SOSE COUNT ; BACK FOR MORE
JRST .-3
TLNN 12, 760000 ; LAST BYTE IN 13?
PUSHJ P, GETWRD ; YES → GET NEXT WORD
ILDB 10, 12 ; GET NEXT ASCII CHARACTER
CAIE 10, 12 ; KEEP TRYING UNTIL LINE-FEED
JRST .-4
SETZM CRDBLK ; I/O STATUS WORD ← -1
SOS CRDBLK
JRST MIXMON ; RETURN TO INSTRUCTION INTERPRETER
GETWRD: SOSG CRDBLK+3 ; DECREMENT CHARACTER COUNT
IN 10, ; COUNT EXHAUSTED, NEXT BUFFER
JRST .+4 ; OK, SO CONTINUE
STATZ 10, 20000 ; TEST WHETHER ERROR WAS EOF
JRST ZEOF ; YES
JRST ZINOUT ; SOME OTHER I/O ERROR
ILDB 10, CRDBLK+2 ; GET INPUT WORD
JUMPE 10,GETWRD ;*RES* IGNORE NULLS AT END OF RECORD
MOVEM 10, IOBUF ; PUT INTO IOBUF
MOVE 12, [POINT 7, IOBUF] ; INITIALIZE BYTE POINTER
POPJ P, ; RETURN
; ****** CARD PUNCH
CPNBLK: BLOCK 10
OUTCPN: SKIPN CPNBLK ; I/O STATUS WORD = 0
JRST ZIOBEG ; → NOT INITED YET
MOVEI 10, =80 ; SET UP COUNTER FOR CHARS
MOVEM 10, COUNT
SETZM IOBUF ; ZERO OUT IOBUF
MOVE 12, [POINT 7, IOBUF] ; INITIALIZE BYTE POINTER
SETZ 11, ; FIX 11 SO CFRMIX WORKS FIRST TIME
CFRMIX
MOVE 10, MIXASC(10) ; CONVERT TO ASCII CODE
IDPB 10, 12 ; PUT INTO IOBUF
TLNN 12, 760000 ; LAST BYTE IN IOBUF?
PUSHJ P, PUTWRD ; YES → OUTPUT IT
SOSE COUNT ; BACK FOR MORE
JRST .-6
MOVEI 10, 15 ; NOW OUTPUT C-R, L-F
IDPB 10, 12
MOVEI 10, 12
IDPB 10, 12
PUSHJ P, PUTWRD
SETZM CPNBLK ; I/O STATUS WORD ← -1
SOS CPNBLK
JRST MIXMON ; RETURN TO INSTRUCTION INTERPRETER
PUTWRD: SOSG CPNBLK+3 ; DECREMENT CHARACTER COUNT
OUT 11, ; OUTPUT THIS BUFFER
SKIPA ; SUCCESS
JRST ZINOUT ; ERROR
MOVE 10, IOBUF ; GET OUTPUT WORD
IDPB 10, CPNBLK+2 ; PUT ONTO FILE
SETZM IOBUF ; ZERO OUT IOBUF
MOVE 12, [POINT 7, IOBUF] ; INITIALIZE BYTE POINTER
POPJ P, ; RETURN
; ****** TYPEWRITER (IN)
TINBLK: BLOCK 10
INTIN: MOVEI 10, =70 ; SET UP COUNTER
MOVEM 10, COUNT
INCHWL 10 ; GET FIRST CHAR OF LINE
SKIPA ; FOR FIRST TIME
INCHRW 10 ; GET NEXT CHAR
CAIN 10, 15 ; CARRIAGE-RETURN →
JRST .+6 ; FINISH LINE WITH BLANKS
MOVE 10, ASCMIX(10) ; CONVERT TO MIX CODE
CTOMIX
SOSE COUNT ; BACK FOR MORE
JRST .-6
JRST .+5 ; NOW GO TO END OF LINE
SETZ 10, ; MIX CODE FOR <BLANK> IS 00
CTOMIX
SOSE COUNT ; BACK FOR MORE
JRST .-3
INCHRW 10 ; KEEP TRYING UNTIL LINE-FEED
CAIE 10, 12
JRST .-2
SETZM TINBLK ; I/O STATUS WORD ← -1
SOS TINBLK
JRST MIXMON ; RETURN TO INSTRUCTION INTERPRETER
; ****** TYPEWRITER (OUT)
TOTBLK: BLOCK 10
OUTTOT: MOVEI 10, =70 ; SET UP COUNTER FOR CHARS
MOVEM 10, COUNT
SETZ 11, ; FIX 11 SO CFRMIX WORKS FIRST TIME
CFRMIX
MOVE 10, MIXASC(10) ; CONVERT TO ASCII CODE
OUTCHR 10 ; OUTPUT IT
SOSE COUNT ; BACK FOR MORE
JRST .-4
MOVEI 10, 15 ; NOW OUTPUT C-R, L-F
OUTCHR 10
MOVEI 10, 12
OUTCHR 10
SETZM TOTBLK ; I/O STATUS WORD ← -1
SOS TOTBLK
JRST MIXMON ; RETURN TO INSTRUCTION INTERPRETER
; ****** PRINTER
PRNBLK: BLOCK 10
OUTPRN: SKIPN PRNBLK ; I/O STATUS WORD = 0
JRST ZIOBEG ; → NOT INITED YET
MOVEI 10, =120 ; SET UP COUNTER FOR CHARS
MOVEM 10, COUNT
SETZM IOBUF ; ZERO OUT IOBUF
MOVE 12, [POINT 7, IOBUF] ; INITIALIZE BYTE POINTER
SETZ 11, ; FIX 11 SO CFRMIX WORKS FIRST TIME
CFRMIX
MOVE 10, MIXASC(10) ; CONVERT TO ASCII CODE
IDPB 10, 12 ; PUT INTO IOBUF
TLNN 12, 760000 ; LAST BYTE IN IOBUF?
PUSHJ P, PRNWRD ; YES → OUTPUT IT
SOSE COUNT ; BACK FOR MORE
JRST .-6
MOVEI 10, 15 ; NOW OUTPUT C-R, L-F
IDPB 10, 12
SKIPN NOJECT ;*RES* SEE IF PRINT OVER PERF
JRST .+6 ;*RES* NO
MOVEI 10,177 ;*RES*
IDPB 10,12 ;*RES* LPT LIKES 177&21 FOR LF ALSO
MOVEI 10,21 ;*RES*
IDPB 10,12 ;*RES*
JRST .+3 ;*RES*
MOVEI 10, 12
IDPB 10, 12
PUSHJ P, PRNWRD
SETZM PRNBLK ; I/O STATUS WORD ← -1
SOS PRNBLK
JRST MIXMON ; RETURN TO INSTRUCTION INTERPRETER
PRNWRD: SOSG PRNBLK+3 ; DECREMENT CHARACTER COUNT
OUT 12, ; OUTPUT THIS BUFFER
SKIPA ; SUCCESS
JRST ZINOUT ; ERROR
MOVE 10, IOBUF ; GET OUTPUT WORD
IDPB 10, PRNBLK+2 ; PUT ONTO FILE
SETZM IOBUF ; ZERO OUT IOBUF
MOVE 12, [POINT 7, IOBUF] ; INITIALIZE BYTE POINTER
POPJ P, ; RETURN
COMMENT ⊗ these are the other i/o related operations
⊗
IOC: MOVE 12,MSPEC ; the only one we'll allow is IOC 0,(18)
JUMPN 12, ZIOC ; so if M in non-zero, it's an error
LDB 11, [POINT 6, INSTR, 29] ; now get F-field
CAIE 11, =18 ; if F 18?
JRST ZIOC ; no → error
MOVE 10, PRNLOK ; wait until printer is finished
CAMLE 10, EXTIME ; do this by changing EXTIME if necessary
MOVEM 10, EXTIME ; it is necessary
MOVE 10, EXTIME ; now we must interlock the printer for the form-feed
ADDI 10, =1000 ; we will use 1000u
MOVEM 10, PRNLOK ; establish interlock time
SETOM PRNLOK+1 ; use range -1:-1
SETOM PRNLOK+2
MOVEI 10, 6430 ;*RES* this is a carriage-return, form-feed
MOVEM 10, IOBUF ; so this is <null><null><null><c-r><f-f>
SKIPN PRNBLK ; is printer inited?
JRST ZIOBEG ; no → txis is an error
PUSHJ P,PRNWRD ;*RES* now send the new page stuff
SETOM PRNBLK ; i/o status word ← -1
JRST MIXMON ; and return to instruction interpreter
JBUS: MOVE 12,MSPEC ; first we see whether it is JBUS *
CAMN 12, ISPEC ; does it match address of present instruction
JRST JBUS1 ; yes → special case
MOVSI 10, (<CAMGE 10,>) ; no → use same routine as JRED
JRST JRB
JBUS1: LDB 11, [POINT 6, INSTR, 29] ; get F-field
CAIL 11, =16 ; is it a legal unit?
CAILE 11, =19
JRST ZDEV ; no → error
MOVE 10, EXTIME ; save EXTIME so we get a count of number of executions
MOVEM 10, JBUSX
HLRZ 10, LOCK1(11) ; get address to check for input busy
JUMPE 10, .+4 ; no such address → don't check
MOVE 10, (10) ; get time when device is finished
CAML 10, EXTIME ; and see whether it has happened
MOVEM 10, EXTIME ; no → change so it has
HRRZ 10, LOCK1(11) ; address to check for output busy
JUMPE 10, .+4 ; no address → don't check
MOVE 10, (10) ; get time device is finished
CAML 10, EXTIME ; and see whether time has come pass
MOVEM 10, EXTIME ; no → now it has
MOVE 10, EXTIME ; calculate number of executions
SUBM 10, JBUSX ; new EXTIME - old EXTIME
SKIPG JBUSX ; any at all?
SETZM JBUSX ; no → make sure it's zero
JRST MIXMON ; so device is no longer busy
JRED: MOVSI 10, (<CAML 10,>) ; so we can use same routine for JBUS, JRED
JRB: HLLM 10, JRB1 ; fix so we do the right compares
HLLM 10, JRB2
MOVE 12,MSPEC ; get address to jump to
TESTM ; is is valid?
LDB 11, [POINT 6, INSTR, 29] ; get F-field
CAIL 11, =16 ; is it valid?
CAILE 11, =19
JRST ZDEV ; no → error
HLRZ 10, LOCK1(11) ; test for input busy
JUMPE 10, .+4 ; no input
MOVE 10, (10) ; get execution time for finishing
JRB1: EXTIME ; this is the crucial compare
JRST MIXMON ; don't want to jump
HRRZ 10, LOCK1(11) ; test for output busy
JUMPE 10, .+4
MOVE 10, (10)
JRB2: EXTIME ; another crucial compare
JRST MIXMON ; don't want to jump
JRST JMP ; we do want to jump
JBUSX: 0 ; this will contain the number of executions of JBUS *